using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Reflection;
using System.Data;

namespace GarbageTruck
{
    public class TemporalExpressionFactory
    {
        public static ITemporalExpression CreateFromString(string expression)
        {
            ITemporalExpression temporalExpression = null;
            Regex regex = new Regex(@"([A-Za-z0-9,: \[\]\(\) ]*\])([UID]{1,1})(\[[A-Za-z0-9,: \[\]\(\) ]*)");
            MatchCollection matches = regex.Matches(expression);
            if (matches.Count > 0)
            {
                temporalExpression = CreateByRelationship(matches[0].Groups[1].Value, matches[0].Groups[0].Value, matches[0].Groups[2].Value);
            }
            else
            {


                regex = new Regex(@"([A-Z]{1,4})?\(([A-Za-z0-9.,:\-/ ]*)?\)");

                MatchCollection debug = regex.Matches(expression);

                string temporalExpressionType = regex.Matches(expression)[0].Groups[1].Value; ;
                string teporalExpressionParameters = regex.Matches(expression)[0].Groups[2].Value;

                DataSet dataSet = new DataSet();
                dataSet.ReadXml("GarbageTruck.xml");
                DataRow row = dataSet.Tables[0].Select("Abreviation = '" + temporalExpressionType + "'")[0];
                if (row != null)
                {

                    Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + @"\" + row["File"].ToString());
                    foreach (Type t in assembly.GetTypes())
                    {
                        if (typeof(ITemporalExpression).IsAssignableFrom(t))
                        {
                            temporalExpression = (ITemporalExpression)Activator.CreateInstance(t, new object[] { teporalExpressionParameters });
                        }
                    }
                }
            }

            return temporalExpression;
        }


        private static ITemporalExpression CreateByRelationship(string relationship, string expression1, string expression2)
        {
            ITemporalExpression temporalExpression = null;
            switch (relationship) 
            {
                case "U":
                    temporalExpression = new TemporalExpressions.Union(CreateFromString(expression1), CreateFromString(expression1));
                    break;

                case "I":
                    temporalExpression = new TemporalExpressions.Intersection(CreateFromString(expression1), CreateFromString(expression1));
                    break;

                case "D":
                    temporalExpression = new TemporalExpressions.Difference(CreateFromString(expression1), CreateFromString(expression1));
                    break;
            }
            return temporalExpression;
        }
    }

}
